#ifndef FGE_GAME_HPP
#define FGE_GAME_HPP

#include <string>

#include "Input.hpp"
#include "MusicManager.hpp"

struct SDL_Surface;

namespace fge
{

class Song;
class SoundEffect;
class Color;
class MusicManager;

// todo: documentation
// screenWidth defaults to 800
// screenHeight defaults to 600
// isFullScreen defaults to false
// enableVerticalSync defaults to true
// windowCaption defaults to "Fallen Game Engine"
// audioFrequency defaults to 44100
// audioChannels defaults to 2
// audioChunkSize defaults to 1024

class Game
{
public:
	Game();
	virtual ~Game();

	virtual void Initialize() { }

	virtual void LoadContent() { }
	virtual void UnloadContent() { }

	virtual void Update(float deltaSeconds) { }
	virtual void Draw() { }

	void Run();

	void ClearScreen(float r, float g, float b, float a);
	void ClearScreen(const Color &color);

	bool WasKeyDown(Key key) const { return lastKeyStates[key]; }
	bool WasKeyUp(Key key) const { return !lastKeyStates[key]; }
	bool IsKeyDown(Key key) const { return currentKeyStates[key]; }
	bool IsKeyUp(Key key) const { return !currentKeyStates[key]; }

	bool IsNewKeyDown(Key key) const { return !lastKeyStates[key] && currentKeyStates[key]; }
	bool IsNewKeyUp(Key key) const { return lastKeyStates[key] && !currentKeyStates[key]; }

	bool WasButtonDown(MouseButton button) const { return lastMouseStates[button]; }
	bool WasButtonUp(MouseButton button) const { return !lastMouseStates[button]; }
	bool IsButtonDown(MouseButton button) const { return currentMouseStates[button]; }
	bool IsButtonUp(MouseButton button) const { return !currentMouseStates[button]; }

	bool IsNewButtonDown(MouseButton button) const { return !lastMouseStates[button] && currentMouseStates[button]; }
	bool IsNewButtonUp(MouseButton button) const { return lastMouseStates[button] && !currentMouseStates[button]; }

	int GetMouseX() const { return mouseX; }
	int GetMouseY() const { return mouseY; }

	int GetScreenWidth() const { return screenWidth; }
	int GetScreenHeight() const { return screenHeight; }

	MusicManager* GetMusicManager() const { return musicManager; }

	void Exit() { exit = true; }

	void ShowCursor(bool value);
	
	int PlaySoundEffect(SoundEffect *soundEffect, bool loop);
	void PauseSoundEffect(int soundEffectHandle);
	void FadeOutSoundEffect(int soundEffectHandle, float seconds);
	void StopSoundEffect(int soundEffectHandle);

protected:
	int screenWidth, screenHeight;
	bool isFullScreen;
	bool enableVerticalSync;

	int audioFrequency, audioChannels, audioChunkSize;

	std::string windowCaption;
	
private:
	SDL_Surface *screenSurface;
	MusicManager *musicManager;

	bool exit;

	bool lastKeyStates[Key_Maximum];
	bool currentKeyStates[Key_Maximum];
	
	int mouseX, mouseY;
	bool lastMouseStates[Mouse_Maximum];
	bool currentMouseStates[Mouse_Maximum];
};

}

#endif//FGE_GAME_HPP
